package aggregate

import (
	"encoding/json"
	"fmt"
	"gluenet/modules/manager/server/domain/dependency"
	"gluenet/modules/manager/server/domain/entity"
	"gluenet/modules/manager/server/domain/vo"
	"gluenet/modules/manager/server/infra"
	"gluenet/modules/manager/server/infra/prepare"
)

func init() {
	//fmt.Printf("init config factory\n")
	prepare.RegisterFactory(func() {
		configMetaFactory := NewConfigCreateFactory()
		prepare.InjectDependency(func() *ConfigCreateFactory {
			return configMetaFactory
		})
	})
}

type ConfigCreateFactory struct {
	ConfigRepo dependency.ConfigMetaRepo
	DetailRepo dependency.DetailRepo
}

func NewConfigCreateFactory() *ConfigCreateFactory {
	factory := &ConfigCreateFactory{}
	prepare.FetchDependency(&factory.ConfigRepo)
	prepare.FetchDependency(&factory.DetailRepo)
	return factory
}

func (factory *ConfigCreateFactory) CreateConfig(req vo.CreateConfigReq) (*entity.Config, error) {
	switch req.Platform {
	case entity.PlatformKubernetes:
		hreq, err := factory.ConfigRepo.AddCharts(req.UserID, req.FileName, req.FileReader)
		if err != nil {
			return nil, fmt.Errorf("add charts %v", err)
		}
		req.Label = "test.helm.charts"
		req.Kind = entity.KindApplication
		req.Version = hreq.Version
		req.Name = hreq.Name
		req.Describe = hreq.Describe
		//req.DetailRepoKey = fmt.Sprintf(infra.DetailRepoKeyFormat, "config", req.Platform, req.UserID, req.Kind, , req.Name)
		req.DetailRepoValues = hreq.DetailRepoValues
	case entity.PlatformGluenets:
		//req.DetailRepoKey = fmt.Sprintf(infra.DetailRepoKeyFormat, "config", req.Platform, req.UserID, req.Kind, req.Label, req.Name)
	}

	var cfg = &entity.Config{}
	if err := cfg.New(req); err != nil {
		return nil, fmt.Errorf("new config entity %v", err)
	}

	cfg.DetailRepoKey = fmt.Sprintf(infra.DetailRepoKeyFormat, "config", cfg.Platform, cfg.UserID, cfg.Kind, cfg.ID, cfg.Name)

	cfgNew, err := factory.ConfigRepo.Add(cfg)
	if err != nil {
		return nil, err
	}

	bts, err := json.Marshal(cfgNew)
	fmt.Printf("cfg %s", bts)

	if err := factory.DetailRepo.PutDetailKV(cfgNew.DetailRepoKey, cfgNew.DetailRepoValue); err != nil {
		factory.ConfigRepo.Del(req.IsAdmin, cfg.UserID, cfgNew.ID)
		return nil, err
	}
	return cfgNew, nil
}
